import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

import model.Signature7;

/*
 * SignatureComparator.java Created on Jan 7, 2008 by M.C.Boulahiya
 */

/**
 * @author M.C.Boulahiya
 * 
 * Compare 2 3D objects signatures contained in SIG files.
 *
 * STEPS :
 *  - Loading 2 signatures files. ==> DONE
 *  - Comparing the two signatures. ==> DONE
 *  - Wrinting a script file that lunch the comparison upon multiple files.  
 *  - Tester avec des tailles differentes. ==> DONE
 */
public class SignatureComparator {
	// 0=Input file assumed good
	// 1=Input file checked for inconsistencies
	// 2=path names
	// 4=flags
	// 8=Timing Info
	// 16=Tokens
	// 32=Token details (use with 16)
	// 64=limits of model coordinates
	// 128=Curvatures
	private static final int DEBUG = 8;
	
	// 200 feature points ==> 1313400		// 330Mo		//
	// 100 feature points ==> 161700		// 	42Mo		//17Mo
	//  50 feature points ==> 19600			// 	 5Mo		// 2.1Mo
	//  20 feature points ==> 1140			// 	 0.3Mo	//
	private int NB_SIG;
	// 19600 4662 1669 ../../DataBase/Potteries/ObjFiles/FScanD27-Bord.obj.sig50 ../../DataBase/Potteries/ObjFiles/FScanD27.obj.sig200
	// 19600 1296 337 ../../DataBase/Potteries/ObjFiles/FScanD27-Bord.obj.sig50 ../../DataBase/Potteries/ObjFiles/ScanRitt5.obj.sig200
	// 19600 19316 82678 ../../DataBase/Potteries/ObjFiles/FScanD27-Bord.obj.sig50 ../../DataBase/Potteries/ObjFiles/ScanD27b-760ko.obj.sig200

	private int nbMean;
	private int nbGaus;
	
	Signature7[] fragmentSig;
	Signature7[] databaseObjectSig;

	
	/**
	 * @param fragment
	 * @param databaseObject
	 */
	public SignatureComparator(int nbSig, int nbGaus, int nbMean, String fragment, String databaseObject) {
		this.NB_SIG = nbSig;
		this.nbGaus = nbGaus;
		this.nbMean = nbMean;
		this.fragmentSig = loadSignature(fragment);
		this.databaseObjectSig = loadSignature(databaseObject);
	}


	/**
	 * @param filename
	 * @return
	 */
	private Signature7[] loadSignature(String filename) {
		long time = System.currentTimeMillis();
		int TAILLE = this.NB_SIG * 2;
		if (filename.endsWith("FScanD27.obj.sig200") || filename.endsWith("ScanRitt5.obj.sig200") 
				|| filename.endsWith("ScanD27b-760ko.obj.sig200") ) {		
			System.out.println("Profile Used");
			TAILLE = this.nbGaus + this.nbMean;
		}
		Signature7[] sgn = null;
		
		// importSignature::begin
		RandomAccessFile infile = null;
		try {
			infile = new RandomAccessFile(filename,"r");
		} catch (FileNotFoundException exception) {
			exception.printStackTrace();
		}
		
		if (infile != null) {	
			try {
				infile.seek(0);
			} catch (IOException exception) {
				exception.printStackTrace();
			}
			
      // readSignature(infile)::begin
			sgn = new Signature7[TAILLE];
			try {
				for (int i = 0; i < sgn.length; i++) {
					String line = infile.readLine();
					if ((DEBUG & 16) != 0)						
						System.out.println("line: " + line);
						
					sgn[i] = new Signature7();
					//TODO mieux traiter le string !
					int deb = 0, fin = line.indexOf(" ");
					sgn[i].nuplet[0] = new Double(line.substring(deb, fin).trim());
		  	 	deb = fin+1;
		  	 	fin = (line.substring(deb)).indexOf(" ");
		  	 	sgn[i].nuplet[1] = new Double(line.substring(deb, deb+fin).trim());
		  	 	deb = deb+fin+1;
		  	 	fin = line.substring(deb).indexOf(" ");
		  	 	sgn[i].nuplet[2] = new Double(line.substring(deb, deb+fin).trim());
		  	 	deb = deb+fin+1;
		  	 	fin = line.substring(deb).indexOf(" ");
		  	 	sgn[i].nuplet[3] = new Double(line.substring(deb, deb+fin).trim());
		  	 	deb = deb+fin+1;
		  	 	fin = line.substring(deb).indexOf(" ");
		  	 	sgn[i].nuplet[4] = new Double(line.substring(deb, deb+fin).trim());
		  	 	deb = deb+fin+1;
		  	 	fin = line.substring(deb).indexOf(" ");
		  	 	sgn[i].nuplet[5] = new Double(line.substring(deb, deb+fin).trim());
		  	 	sgn[i].nuplet[6] = new Double(line.substring(deb+fin).trim());
		    }
    	} catch (EOFException e) {
        //System.out.println("j'ai fini de lire ce fichier !");
			} catch (IOException exception) {
			}// readSignature(infile)::end
		}
		
		if (infile != null) {
      try {
				infile.close();
			} catch (IOException exception) {
				exception.printStackTrace();
			}
    } // importSignature::end
		
		if ((DEBUG & 8) != 0) {
			time = System.currentTimeMillis() - time;
			System.out.println("reading Signature: " + time + " ms");
			time = System.currentTimeMillis();
		}	
		
		return sgn;
	}
	
	/**
	 * 
	 */
	private void compare() {
		long time = System.currentTimeMillis();
		int correspond = 0;
//		for (int i = 0; i < this.NB_SIG; i++) {
//			Signature7 s1 = this.fragmentSig[i];
//			for (int j = 0; j < this.nbGaus; j++) {
//				Signature7 s2 = this.databaseObjectSig[j];
//				if (s1.equals(s2)) { 
//					correspond++;
//					break;
//				}
//			}
//		}
		for (int i = 0; i < this.nbGaus; i++) {
			Signature7 s2 = this.databaseObjectSig[i];
			for (int j = 0; j < this.NB_SIG; j++) {
				Signature7 s1 = this.fragmentSig[j];	
				if (s2.equals(s1)) { 
					correspond++;
					break;
				}
			}
		}		

		if ((DEBUG & 8) != 0) {
			time = System.currentTimeMillis() - time;
			System.out.println("Gaussian Comparison: " + time + " ms");
			time = System.currentTimeMillis();
		}
		if (correspond == 0)
			System.out.println("gaussianCorrespond = "+correspond+" gaussianPourcentage = 0%");
		else
			System.out.println("gaussianCorrespond = " + correspond + " nbGauss = " + 
					this.nbGaus + " gaussianPourcentage = " + 100*correspond/this.nbGaus + "%");
		
		correspond = 0;
//		for (int i = this.NB_SIG; i < this.NB_SIG * 2; i++) {
//			Signature7 s1 = this.fragmentSig[i];
//			for (int j = this.nbGaus; j < this.nbGaus+this.nbMean; j++) {
//				if (s1.equals(this.databaseObjectSig[j])) {
//					correspond++;
//					break;
//				}
//			}
//		}
		for (int j = this.nbGaus; j < this.nbGaus+this.nbMean; j++) {
			Signature7 s1 = this.databaseObjectSig[j];
			for (int i = this.NB_SIG; i < this.NB_SIG * 2; i++) {
				if (s1.equals(this.fragmentSig[i])) {
					correspond++;
					break;
				}
			}
		}

		
		if ((DEBUG & 8) != 0) {
			time = System.currentTimeMillis() - time;
			System.out.println("Mean Comparison: " + time + " ms");
			time = System.currentTimeMillis();
		}		
		if (correspond == 0)
			System.out.println("meanCorrespond = "+correspond+" meanPourcentage = 0%");
		else
			System.out.println("meanCorrespond = " + correspond + " nbMean = " + 
					this.nbMean + " meanPourcentage = " + 100*correspond/this.nbMean + "%");
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//../../DataBase/Potteries/ObjFiles/FScanD27.obj.sig
		//../../DataBase/Potteries/ObjFiles/FScanD27-Bord.obj.sig
		//../../DataBase/Potteries/ObjFiles/FScanD27-Fond.obj.sig
		//../../DataBase/Potteries/ObjFiles/FScanD27-Panse.obj.sig
		System.out.println(args[0]+"\n"+args[1]+"\n"+args[2]+"\n"+args[3]+"\n"+args[4]);
		
		SignatureComparator sc = 
				new SignatureComparator(new Integer(args[0]), 
																new Integer(args[1]),
																new Integer(args[2]),
																args[3], 
																args[4]);

		sc.compare();
	}

}// End of class SignatureComparator

// End of file SignatureComparator.java